#include <QWizard>
#include <QLabel>
#include <QComboBox>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QGridLayout>
#include <QListWidget>
#include <QPushButton>
#include <QMessageBox>

#include "ProjectWizard.hxx"
#include "VideoNewDlg.hxx"
#include "Sequence.hxx"

ProjectWizard::ProjectWizard()
{
    _project = NULL;
    setWizardStyle(QWizard::ClassicStyle);
    addPage(createProjectPage());
    addPage(createClassesPage());
    addPage(createVideosPage());
}

QWizardPage* ProjectWizard::createProjectPage()
{
    QWizardPage* page = new QWizardPage;
    page->setTitle("Project Basic Information");

    QLabel* label = new QLabel("Please Input the Name for the New Project, "
        " and Choose the Type of New Project!");
    label->setWordWrap(true);

    QLabel* lblName = new QLabel("Project Name:");
    _edtProjectName = new QLineEdit();
    _edtProjectName->setText("Project");

    QLabel* lblType = new QLabel("Project Type:");
    _cbProjectType = new QComboBox();
    _cbProjectType->addItem(tr("Object Detection and Tracking"));
    //_cbProjectType->addItem(tr("Fish Tracking"));
    //_cbProjectType->addItem(tr("Video Semantic Segmentation"));


    QVBoxLayout* layout = new QVBoxLayout;
    layout->setSpacing(20);

    QGridLayout* glayout = new QGridLayout();
    glayout->addWidget(lblName, 0, 0);
    glayout->addWidget(_edtProjectName, 0, 1);
    glayout->addWidget(lblType, 1, 0);
    glayout->addWidget(_cbProjectType, 1, 1);
    glayout->setSpacing(20);

    layout->addWidget(label);
    layout->addLayout(glayout);

    page->setLayout(layout);

    return page;
}

QWizardPage* ProjectWizard::createClassesPage()
{
    QWizardPage* page = new QWizardPage;
    page->setTitle("Add Classes for New Project");

    //QLabel* label = new QLabel("Please Add Classes for the New Project!");
    //label->setWordWrap(true);

    QLabel* lblClasses = new QLabel("Class List:");
    _lwClasses = new QListWidget();

    QLabel* lblClassName = new QLabel("Class Name:");
    _edtClassName = new QLineEdit();
    _edtClassName->setText(tr("Class Name"));
    _btnAddClass = new QPushButton("Add Class");
    _btnDelClass = new QPushButton("Delete Class");
    _btnDelClass->setEnabled(false);

    connect(_btnAddClass, SIGNAL(clicked()), this, SLOT(addClass()));
    connect(_btnDelClass, SIGNAL(clicked()), this, SLOT(delClass()));
    connect(_lwClasses, SIGNAL(itemSelectionChanged()), this, SLOT(classSelectionChanged()));

    QVBoxLayout* layout = new QVBoxLayout;
    layout->setSpacing(20);

    QGridLayout* glayout = new QGridLayout();
    glayout->addWidget(lblClasses, 0, 0,1,2);
    glayout->addWidget(_lwClasses, 1, 0,5,1);
    glayout->addWidget(lblClassName, 1, 1);
    glayout->addWidget(_edtClassName, 2, 1);
    glayout->addWidget(_btnAddClass, 3, 1);
    glayout->addWidget(_btnDelClass, 4, 1);
    glayout->setSpacing(20);

    layout->addLayout(glayout);

    page->setLayout(layout);

    return page;
}

QWizardPage* ProjectWizard::createVideosPage()
{
    QWizardPage* page = new QWizardPage;
    page->setTitle("Add Sequences for New Project");

    QLabel* lblSequenceList = new QLabel("Sequence List:");
    _lwVideos = new QListWidget();

    _btnAddVideo = new QPushButton("Add Video");
    _btnDelVideo = new QPushButton("Delete Video");
    _btnDelVideo->setEnabled(false);

    connect(_btnAddVideo, SIGNAL(clicked()), this, SLOT(addVideo()));
    connect(_btnDelVideo, SIGNAL(clicked()), this, SLOT(delVideo()));
    connect(_lwVideos, SIGNAL(itemSelectionChanged()), this, SLOT(videoSelectionChanged()));

    QVBoxLayout* layout = new QVBoxLayout;
    layout->setSpacing(20);

    QGridLayout* glayout = new QGridLayout();
    glayout->addWidget(lblSequenceList, 0, 0, 1, 2);
    glayout->addWidget(_lwVideos, 1, 0, 5, 1);
    glayout->addWidget(_btnAddVideo, 3, 1);
    glayout->addWidget(_btnDelVideo, 4, 1);
    glayout->setSpacing(20);

    layout->addLayout(glayout);

    page->setLayout(layout);

    return page;
}

void ProjectWizard::addClass()
{
    QString strClass = _edtClassName->text();

    if (strClass.trimmed().length() > 0)
    {
        _lwClasses->addItem(strClass.trimmed());
        _edtClassName->setText("");
        _edtClassName->setFocus();
    }
    else
    {
        QMessageBox::warning(this, "Warning", "Please input a valid Class Name!");
        return;
    }
}

void ProjectWizard::delClass()
{
    if (_lwClasses->currentRow() >= 0)
    {
        _lwClasses->takeItem(_lwClasses->currentRow());
    }
}

void ProjectWizard::classSelectionChanged()
{
    if (_lwClasses->currentRow() >= 0)
        _btnDelClass->setEnabled(true);
    else
        _btnDelClass->setEnabled(false);
}

void ProjectWizard::addVideo()
{
    VideoInfo* vi = new VideoInfo();
    VideoNewDialog vnd;
    vnd.setVideoInfo(vi);
    
    if (vnd.exec() == QDialog::Accepted)
    {
        QListWidgetItem* item = new QListWidgetItem(vi->VideoName);

        QVariant data;
        data.setValue(vi);

        item->setData(Qt::UserRole, data);

        _lwVideos->addItem(item);
    }
    else
    {
        delete vi;
    }
}

void ProjectWizard::delVideo()
{
    if (_lwVideos->currentRow() >= 0)
    {
        QListWidgetItem* item = _lwVideos->takeItem(_lwVideos->currentRow());
        QVariant data = item->data(Qt::UserRole);
        VideoInfo* vi = data.value<VideoInfo*>();
        if (vi) delete vi;
    }
}

void ProjectWizard::videoSelectionChanged()
{
    if (_lwVideos->currentRow() >= 0)
        _btnDelVideo->setEnabled(true);
    else
        _btnDelVideo->setEnabled(false);
}

void ProjectWizard::done(int r)
{
    if (r == QDialog::Rejected)
    {
        QDialog::done(QDialog::Rejected);
        return;
    }
    
    if (_edtProjectName->text().trimmed().length() <= 0)
    {
        QMessageBox::warning(this, "Warnning", "Please Specify a Name for New Project!");
        restart();
        return;
    }

    if (_lwClasses->count() <= 0)
    {
        QMessageBox::warning(this, "Warnning", "Please Add at Least One Class for New Project!");
        restart();
        return;
    }

    if (_lwVideos->count() <= 0)
    {
        QMessageBox::warning(this, "Warnning", "Please Add at Least One Video for New Project!");
        restart();
        return;
    }

    assert(_project);

    _project->setName(_edtProjectName->text().trimmed().toStdString());
    _project->setProjectType(ProjectType::TYPE_RECTANGLE);

    for (int i = 0; i < _lwClasses->count(); i++)
    {
        QString strClass = _lwClasses->item(i)->text().trimmed();
        _project->addClass(strClass.toStdString());
    }

    for (int i = 0; i < _lwVideos->count(); i++)
    {
        QListWidgetItem* item = _lwVideos->item(i);

        QVariant data = item->data(Qt::UserRole);
        VideoInfo* vi = data.value<VideoInfo*>();

        Sequence* sequence = new Sequence();
        sequence->setFilePath(vi->VideoFile.toStdString());
        sequence->setId(_project->getNextSequenceId());
        sequence->setName(vi->VideoName.toStdString());
        sequence->setType(SequenceType::VIDEO_SEQUENCE);
        sequence->setFrameStrip(vi->FrameStrip);

        _project->addSequence(sequence);
    }

    QDialog::done(QDialog::Accepted);
}